package com.cheer.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheer.common.Page;
import com.cheer.dao.OaMatrixDao;
import com.cheer.dto.OaMatrixAddDTO;
import com.cheer.dto.OaMatrixUpdateDTO;
import com.cheer.entity.OaMatrixEntity;
import com.cheer.exception.ServiceException;
import com.cheer.service.OaMatrixClassService;
import com.cheer.service.OaMatrixService;
import com.cheer.vo.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service("oaMatrixService")
public class OaMatrixServiceImpl extends ServiceImpl<OaMatrixDao, OaMatrixEntity> implements OaMatrixService {

    @Value("${image.url}")
    private String imageUrl;

    @Autowired
    private OaMatrixDao oaMatrixDao;

    @Autowired
    private OaMatrixClassService oaMatrixClassService;

    @Override
    public void deleteByPid(Integer pid) {
        oaMatrixDao.deleteByPid(pid);
    }

    @Override
    @Transactional
    public void add(OaMatrixAddDTO matrixAddDTO) {
        if (matrixAddDTO.getSort() == null || matrixAddDTO.getSort() <= 0) {
            matrixAddDTO.setSort(1);
        }

        oaMatrixDao.incrSort(matrixAddDTO.getSort());

        OaMatrixEntity matrix = new OaMatrixEntity()
                .setName(matrixAddDTO.getName())
                .setImgUrl(matrixAddDTO.getImgUrl())
                .setHref(matrixAddDTO.getHref())
                .setSort(matrixAddDTO.getSort())
                .setPid(matrixAddDTO.getPid())
                .setAddTime(String.valueOf(DateUtil.currentSeconds()));

        oaMatrixDao.insert(matrix);
    }

    @Override
    public Page<OaMatrixListVO> list(Integer pageNum, Integer pageSize) {
        IPage<OaMatrixEntity> page = oaMatrixDao.selectPage(pageNum, pageSize);

        Set<Integer> pidSet = page.getRecords().stream()
                .map(OaMatrixEntity::getPid)
                .collect(Collectors.toSet());

        Map<Integer, String> nameMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(pidSet)) {
            oaMatrixClassService.listByIds(pidSet)
                    .forEach(matrixClass -> nameMap.put(matrixClass.getId(), matrixClass.getName()));
        }

        List<OaMatrixListVO> matrixListVOList = page.getRecords().stream()
                .map(matrix -> new OaMatrixListVO()
                        .setId(matrix.getId())
                        .setName(matrix.getName())
                        .setPname(nameMap.get(matrix.getPid()))
                        .setImgUrl(imageUrl + matrix.getImgUrl())
                        .setHref(matrix.getHref())
                        .setSort(matrix.getSort())
                        .setAddTime(matrix.getAddTime()))
                .collect(Collectors.toList());

        return new Page<>(page, matrixListVOList);
    }

    @Override
    @Transactional
    public void delete(Integer id) {
        OaMatrixEntity matrix = oaMatrixDao.selectById(id);
        if (matrix == null) {
            throw new ServiceException("矩阵不存在");
        }

        oaMatrixDao.deleteById(id);
        oaMatrixDao.decrSort(matrix.getSort());
    }

    @Override
    public OaMatrixInfoVO info(Integer id) {
        OaMatrixEntity matrix = oaMatrixDao.selectById(id);
        if (matrix == null) {
            throw new ServiceException("矩阵不存在");
        }

        return new OaMatrixInfoVO()
                .setId(matrix.getId())
                .setName(matrix.getName())
                .setHref(matrix.getHref())
                .setPid(matrix.getPid())
                .setSort(matrix.getSort())
                .setImgUrl(new ImageVO()
                        .setFullUrl(imageUrl + matrix.getImgUrl())
                        .setShortUrl(matrix.getImgUrl()));
    }

    @Override
    @Transactional
    public void update(OaMatrixUpdateDTO matrixUpdateDTO) {
        OaMatrixEntity matrix = oaMatrixDao.selectById(matrixUpdateDTO.getId());
        if (matrix == null) {
            throw new ServiceException("矩阵不存在");
        }

        if (matrixUpdateDTO.getSort() != null) {
            if (matrixUpdateDTO.getSort() <= 0) {
                matrixUpdateDTO.setSort(1);
            }
            if (matrix.getSort() > matrixUpdateDTO.getSort()) {
                oaMatrixDao.incrSortRange(matrixUpdateDTO.getSort(), matrix.getSort());
            } else if (matrix.getSort() < matrixUpdateDTO.getSort()) {
                oaMatrixDao.decrSortRange(matrix.getSort(), matrixUpdateDTO.getSort());
            }
        }

        OaMatrixEntity updateMatrix = new OaMatrixEntity()
                .setId(matrixUpdateDTO.getId())
                .setName(matrixUpdateDTO.getName())
                .setImgUrl(matrixUpdateDTO.getImgUrl())
                .setHref(matrixUpdateDTO.getHref())
                .setSort(matrixUpdateDTO.getSort())
                .setPid(matrixUpdateDTO.getPid());

        oaMatrixDao.updateById(updateMatrix);
    }

    @Override
    public OaMatrixFrontVO listByMatrixClass(Integer pid) {
        OaMatrixFrontVO matrixFrontVO = new OaMatrixFrontVO();

        List<SimpleObjectVO> matrixClassList = oaMatrixClassService.listSimpleByPid(pid);
        matrixFrontVO.setSingle(CollectionUtils.isEmpty(matrixClassList));

        List<OaMatrixEntity> matrixList = oaMatrixDao.selectListByPid(pid);
        matrixFrontVO.setItemList(matrixList.stream()
                .map(oaMatrixEntity -> new OaMatrixFrontItemVO()
                        .setId(oaMatrixEntity.getId())
                        .setImgUrl(imageUrl + oaMatrixEntity.getImgUrl())
                        .setName(oaMatrixEntity.getName()))
                .collect(Collectors.toList()));

        if (!matrixFrontVO.getSingle()) {
            List<Integer> pids = matrixClassList.stream()
                    .map(simpleObjectVO -> simpleObjectVO.getId().intValue())
                    .collect(Collectors.toList());
            Map<Integer, List<OaMatrixEntity>> oaMatrixEntityList = oaMatrixDao.selectListByPids(pids).stream()
                    .collect(Collectors.groupingBy(OaMatrixEntity::getPid));

            List<OaMatrixFrontListVO> matrixFrontListVOList = new ArrayList<>();
            for (SimpleObjectVO simpleObjectVO : matrixClassList) {
                OaMatrixFrontListVO oaMatrixFrontListVO = new OaMatrixFrontListVO()
                        .setName(simpleObjectVO.getName());

                List<OaMatrixEntity> oaMatrixEntities = oaMatrixEntityList.get(simpleObjectVO.getId().intValue());
                if (oaMatrixEntities != null) {
                    oaMatrixFrontListVO.setItemList(oaMatrixEntities.stream()
                            .sorted(Comparator.comparingInt(OaMatrixEntity::getSort))
                            .map(oaMatrixEntity -> new OaMatrixFrontItemVO()
                                    .setId(oaMatrixEntity.getId())
                                    .setImgUrl(imageUrl + oaMatrixEntity.getImgUrl())
                                    .setName(oaMatrixEntity.getName()))
                            .collect(Collectors.toList()));
                }

                matrixFrontListVOList.add(oaMatrixFrontListVO);
            }
            matrixFrontVO.setMatrixList(matrixFrontListVOList);
        }

        return matrixFrontVO;
    }

    @Override
    public String getHref(Integer id) {
        OaMatrixEntity matrix = oaMatrixDao.selectById(id);
        if (matrix == null) {
            return null;
        }

        return matrix.getHref();
    }
}